package com.ea.common.annotation;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;

import java.util.Map;


import javax.servlet.http.HttpServletRequest;


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ea.common.utils.HttpKit;

import com.ea.modular.model.sys.Log;
import com.ea.modular.model.sys.ShiroUser;
import com.ea.modular.utils.sys.UserUtil;

import io.swagger.annotations.ApiOperation;

/**
 * 统一日志处理
 * 
 * @author邢广军
 *
 */
@Aspect
@Component
public class LogAdvice {

	


	@Around(value = "@annotation(com.ea.common.annotation.LogAnnotation)")
	public Object logSave(ProceedingJoinPoint point) throws Throwable {

		MethodSignature signature = (MethodSignature) point.getSignature();
		Method method = signature.getMethod(); //获取被拦截的方法
		String methodName = method.getName(); //获取被拦截的方法名

		//获取拦截方法的参数
		String className = point.getTarget().getClass().getName();//获取类名

		LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
		String ApiName = annotation.value();
		if (StringUtils.isEmpty(ApiName)) {
			ApiOperation apiOperation = signature.getMethod().getDeclaredAnnotation(ApiOperation.class);
			if (apiOperation != null) {
				ApiName = apiOperation.value();
			}
		}

		ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 
		HttpServletRequest request = requestAttributes.getRequest();
		String url=request.getRequestURL().toString();
		String methods=request.getMethod();
		Map<String, String> parameters = HttpKit.getRequestParameters();
		String ip=getIP(request);
		


		try {
			Object object = point.proceed();
		
			insertLog(methodName,ApiName,methods,url,parameters.toString(),"成功",className,ip,"0");
			return object;
		} catch (Exception e) {
		
			insertLog(methodName,ApiName,methods,url,parameters.toString(),getStackTraceAsString(e),className,ip,"1");
			throw e;
		}


	}
	private void insertLog(String methodName,String ApiName,String methods,String url,String parameters,String msg,String className,String ip,String type){
		//封装添加到数据库
		Log log= new Log();
		log.setStatus(methodName);
		log.setTitle(ApiName);
		log.setMethod(methods);
		log.setRequestUri(url);
		log.setParams(parameters);
		log.setException(msg);
		log.setUserAgent(className);
		log.setRemoteAddr(ip);
		log.setOpsType(type);

		ShiroUser shiroUser = UserUtil.getCurrentUser();
		log.setCreateBy(shiroUser);
		LogManager.me().executeLog(LogTaskFactory.saveTaskLog(log));
	}
	/**
	 * 将ErrorStack转化为String.
	 */
	public String getStackTraceAsString(Throwable e) {
		if (e == null){
			return "";
		}
		StringWriter stringWriter = new StringWriter();
		e.printStackTrace(new PrintWriter(stringWriter));
		return stringWriter.toString();
	}
	
	/**
     * 从Request对象中获得客户端IP，处理了HTTP代理服务器和Nginx的反向代理截取了ip
     * @param request
     * @return ip
     */
	public static String getIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (!checkIP(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (!checkIP(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (!checkIP(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    private static boolean checkIP(String ip) {
        if (ip == null || ip.length() == 0 || "unkown".equalsIgnoreCase(ip)
                || ip.split(".").length != 4) {
            return false;
        }
        return true;
    }
	
	






}
